//*********************************************************
//
//    Copyright (c) Microsoft. All rights reserved.
//    This code is licensed under the Apache License, Version 2.0.
//    THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
//    ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
//    IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
//    PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************

namespace Microsoft.Research.ScientificWorkflow.UIDesigner.Monitor
{
    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Linq;
    using Microsoft.Research.ScientificWorkflow.UIDesigner.Commands;
    using Microsoft.Research.ScientificWorkflow.UIDesigner.WpfComposite;
    using Microsoft.Practices.Unity;
    using Microsoft.Research.eResearch.Subscriber.Interfaces;

    public class PerformancePresentationModel
    {
        internal class PerformanceCounterMap
        {
            public string Concept { get; set; }

            public string Name { get; set; }

            public string XAxisLabel { get; set; }

            public string YAxisLabel { get; set; }
        }

        private PerformanceCounterMap[] counterMaps = new PerformanceCounterMap[] 
        { 
            new PerformanceCounterMap { Concept = "trident:CpuResource", Name = "CPU", XAxisLabel="Time (in seconds)", YAxisLabel="Usage (as a percentage)"},
            new PerformanceCounterMap { Concept = "trident:MemoryResource", Name = "Memory", XAxisLabel="Time (in seconds)", YAxisLabel="Usage (in megabytes)"}
        };

        private Dictionary<string, PerformanceCounterviewModel> countersLookup = new Dictionary<string, PerformanceCounterviewModel>();

        public PerformanceView View { get; private set; }

        public ObservableCollection<PerformanceCounterviewModel> Counters { get; private set; }

        public PerformancePresentationModel(IUnityContainer container, PerformanceView view, JobCommandProxy jobCommandProxy)
        {
            this.View = view;
            this.Counters = new ObservableCollection<PerformanceCounterviewModel>();

            // container.Resolve<IMonitorService>().WorkflowInstanceCreated += delegate { this.ClearCharts(); };
            container.Resolve<IMonitorService>().ResourceUsage += OnResourceUsageEvent;
            container.Resolve<IMonitorService>().Clear += delegate { this.ClearCharts(); };
            jobCommandProxy.ExecuteCommand.RegisterCommand(new DelegateCommand<object>(p => { this.ClearCharts(); }));

            this.IntialiseCounter();
            this.View.Model = this.Counters;
        }

        /// <summary>
        /// Event hander to clear the ActivityCollection
        /// </summary>
        /// <param name="sender">object</param>
        /// <param name="e">EventArgs</param>
        private void OnClearEvent(object sender, EventArgs e)
        {
            this.Counters.Clear();
        }

        private void IntialiseCounter()
        {
            foreach (PerformanceCounterMap counterMap in this.counterMaps)
            {
                PerformanceCounterviewModel counter = new PerformanceCounterviewModel(counterMap.Concept, counterMap.Name, counterMap.XAxisLabel, counterMap.YAxisLabel);
                this.countersLookup.Add(counterMap.Concept, counter);
                this.Counters.Add(counter);
            }
        }

        private void OnResourceUsageEvent(object sender, BlackboardMessageReceivedEventArgs e)
        {
            foreach (PerformanceCounterMap counterMap in this.counterMaps)
            {
                if (e.IncomingMessage.Keys.Contains(counterMap.Concept))
                {
                    PerformanceCounterviewModel model = countersLookup[counterMap.Concept];
                    model.ProcessMessage(e.IncomingMessage);
                    break;
                }
            }
        }

        private void ClearCharts()
        {
            foreach (PerformanceCounterviewModel viewModel in countersLookup.Values)
            {
                viewModel.ClearChart();
            }
        }
    }
}
